Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#18] useQuery, useInfiniteQuery -> useSuspenseQuery, useSuspenseInfiniteQuery 교체 #19

Merged
merged 10 commits into from
Jan 15, 2025

Conversation

lee0jae330
Copy link
Member

🔗 #18

🙋‍ Summary (요약)

  • 기존 useQuery, useInfiniteQuerySuspense를 활용할 수 있는 useSuspenseQuery, useSuspenseInfiniteQuery로 교체하였습니다.

😎 Description (변경사항)

useQuery, useInfiniteQuery -> useSuspenseQuery, useSuspenseInfiniteQuery 교체

  • React의 철학인 선언적인 프로그래밍을 적극적으로 반영하고자 기존 명령형 프로그래밍 성격이 강했던 기존 방식을 Suspense를 활용한 방식으로 바꾸고자 진행한 작업입니다.
  • Suspense 관련 학습 정리

명령적, 선언적 프로그래밍에 대한 간단한 설명

  • 명령적 프로그래밍
    • 어떻게 해야 하는가? 에 초점을 맞춘 프로그래밍 스타일
    • 작업을 수행하기 위한 절차나 명령의 흐름을 명확히 정의하는 방식

예시

if(isError)
   return <Error컴포넌트/> 
if(loading) 
  return <로딩컴포넌트/>
return  <컴포넌트 />
  • 설명 : 에러 발생 시 Error 컴포넌트를 렌더링하고 로딩 시에는 로딩 컴포넌트를 렌더링하고 그렇지 않으면 보여주려고 한 컴포넌트를 렌더링하라고 절차를 정의함

  • 선언적 프로그래밍

    • **무엇을 해야 하는가?**에 초점을 맞춘 프로그래밍 스타일
    • 결과를 정의하지만 그것을 얻는 방법(절차)은 시스템에 위임하는 방식

예시

<ErrorBoundary fallback={에러컴포넌트}>
  <Suspense fallback={로딩컴포넌트}>
      <비동기 데이터를 불러오는 컴포넌트/>
  <Suspense/>
  • 설명 : 개발자는 UI 로직에만 집중하면 됨. 에러 처리와 로딩 처리는 ErrorBounday, Suspense 컴포넌트가 처리함 (시스템에 위임)

useGetWorkspace 훅에서 useSuspenseQuery를 사용하도록 교체

  • 기존에 사용하던 useQueryuseSuspenseQuery로 교체함
기존 코드
export const useGetWorkspace = (workspaceId: string) => {
  const workspaceApi = WorkspaceApi();
  const userId = getUserId() || createUserId();
  const { initCssPropertyObj } = useCssPropsStore();
  const { initClassBlockList } = useClassBlockStore();
  const { setCanvasInfo, setName } = useWorkspaceStore();
  const { resetChangedStatusState } = useWorkspaceChangeStatusStore();
  const { setIsResetCssChecked } = useResetCssStore();
  const { setInitialImageMap, setInitialImageList } = useImageModalStore();
  const { data, isPending, isError } = useQuery({
    queryKey: workspaceKeys.detail(workspaceId),
    queryFn: () => {
      return workspaceApi.getWorkspace(userId, workspaceId);
    },
  });

  useEffect(() => {
    resetChangedStatusState();
  }, []);

  useEffect(() => {
    if (isError) {
      toast.error('워크스페이스 정보 불러오기 실패');
      return;
    }
    if (!data) {
      return;
    }

    if (!data.workspaceDto) {
      return;
    }
    setName(data.workspaceDto.name);
    Object.keys(data.workspaceDto.totalCssPropertyObj).forEach((className) => {
      createCssClassBlock(className);
    });

    initCssPropertyObj(data.workspaceDto.totalCssPropertyObj);
    initClassBlockList(
      Object.keys(data.workspaceDto.totalCssPropertyObj).map((className) =>
        removeCssClassNamePrefix(className)
      )
    );
    setCanvasInfo(data.workspaceDto.canvas);
    cssStyleToolboxConfig.contents = data.workspaceDto.classBlockList
      ? JSON.parse(data.workspaceDto.classBlockList)
      : [];
    setIsResetCssChecked(data.workspaceDto.isCssReset);
    setInitialImageMap(data.workspaceDto.imageMap);
    setInitialImageList(data.workspaceDto.imageList);
  }, [isError, data]);
  return { data, isPending, isError };
};
변경된 코드
export const useGetWorkspace = (workspaceId: string) => {
  const workspaceApi = WorkspaceApi();
  const userId = getUserId() || createUserId();
  const { initCssPropertyObj } = useCssPropsStore();
  const { initClassBlockList } = useClassBlockStore();
  const { setCanvasInfo, setName } = useWorkspaceStore();
  const { resetChangedStatusState } = useWorkspaceChangeStatusStore();
  const { setIsResetCssChecked } = useResetCssStore();
  const { setInitialImageMap, setInitialImageList } = useImageModalStore();
  const { data, isPending, isError } = useSuspenseQuery({
    queryKey: workspaceKeys.detail(workspaceId),
    queryFn: () => {
      resetChangedStatusState();
      return workspaceApi.getWorkspace(userId, workspaceId);
    },
  });

  useEffect(() => {
    if (!isError || !data || !data.workspaceDto) {
      return;
    }

    setName(data.workspaceDto.name);
    Object.keys(data.workspaceDto.totalCssPropertyObj).forEach((className) => {
      createCssClassBlock(className);
    });

    initCssPropertyObj(data.workspaceDto.totalCssPropertyObj);
    initClassBlockList(
      Object.keys(data.workspaceDto.totalCssPropertyObj).map((className) =>
        removeCssClassNamePrefix(className)
      )
    );
    setCanvasInfo(data.workspaceDto.canvas);
    cssStyleToolboxConfig.contents = data.workspaceDto.classBlockList
      ? JSON.parse(data.workspaceDto.classBlockList)
      : [];
    setIsResetCssChecked(data.workspaceDto.isCssReset);
    setInitialImageMap(data.workspaceDto.imageMap);
    setInitialImageList(data.workspaceDto.imageList);
  }, [isError, data]);
  return { data, isPending, isError };
};
  • 변경 전 : useGetWorkspace훅에 에러 처리를 해야 했음

  • 변경 후 : 데이터 페칭 성공 시 전역 상태를 초기화하는 작업만 진행

  • WorkspacePage 컴포넌트 변경점

기존

  if (isError) {
    return <NotFound />;
  }

  return (
    <>
      <div className="flex h-screen flex-col">
        {isPending && <Loading />}
        {isCoachMarkOpen && <CoachMark />}
        <WorkspacePageHeader />
        <WorkspaceContent />
      </div>
      <ImageTagModal />
    </>
  );
  • 에러, 로딩 처리를 해줘야 했음

변경 후

  • 에러, 로딩 처리 코드 삭제
  • App.tsx에서 설정하는 createBrowserRouter에서 ErrorBoundarySuspense를 통해 에리 및 로딩 처리 진행

useGetWorkspaceList 훅에서 useSuspenseInfiteQuery를 사용하도록 교체

  • useInfiteQuery -> useSuspenseQuery로 교체

  • useGetWorkspaceList 변경점

    • useInfiteQuery -> useSuspenseQuery만 변경
  • 기존 WorkspaceContainer 변경점

    • 기존에 사용하던 WorkspaceContainer 라는 컴포넌트명은 workspace만을 감싸고 있는 느낌이 강함. 하지만 WorkspaceHeader 컴포넌트도 감싸고 있었음
    • 의미를 명확하게 하기 위해 WorkspaceSection으로 컴포넌트명 변경
    • Workspace Item이 렌더링되는 부분을 WorkspaceContainer 컴포넌트로 분리함
    • 또한 무한스크롤, 가상스크롤 관련 로직도 제거함
    • WorkspaceContainer 컴포넌트를 Suspense로 감싸 로딩 처리 진행
기존 코드
export const WorkspaceContainer = () => {
  const { hasNextPage, fetchNextPage, isPending, isFetchingNextPage, isError, workspaceList } =
    useGetWorkspaceList();

  const { renderedData, offsetY, totalHeight } = useVirtualScroll<TWorkspace>({
    data: workspaceList,
    topSectionHeight: 594,
    renderedItemHeight: 262,
    gapY: 32,
  });

  const fetchCallback: IntersectionObserverCallback = (entries, observer) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting && hasNextPage) {
        fetchNextPage();
        observer.unobserve(entry.target);
      }
    });
  };

  const nextFetchTargetRef = useInfiniteScroll({ intersectionCallback: fetchCallback });

  return (
    <section className="w-full max-w-[1152px] px-3 pb-48">
      <WorkspaceHeader />
      {isPending && (
        <WorkspaceGrid>
          <SkeletonWorkspaceList skeletonNum={8} />
        </WorkspaceGrid>
      )}
      {isError ? (
        <WorkspaceLoadError />
      ) : (
        workspaceList &&
        (workspaceList.length === 0 ? (
          <EmptyWorkspace />
        ) : (
          <div
            style={{
              height: `${totalHeight}px`,
            }}
          >
            <WorkspaceGrid offsetY={offsetY}>
              <WorkspaceList workspaceList={renderedData} />
              {isFetchingNextPage && <SkeletonWorkspaceList skeletonNum={8} />}
            </WorkspaceGrid>
          </div>
        ))
      )}
      {!isPending && !isFetchingNextPage && hasNextPage && (
        <div ref={nextFetchTargetRef} className="h-3 w-full"></div>
      )}
    </section>
  );
};
변경된 코드
export const WorkspaceSection = () => {
  return (
    <section className="w-full max-w-[1152px] px-3 pb-48">
      <WorkspaceHeader />
      <Suspense fallback={<SkeletonWorkspaceList skeletonNum={8} />}>
        <WorkspaceContainer />
      </Suspense>
    </section>
  );
};
  • 새로운 WorkspaceContainer 컴포넌트
  • useGetWorkspaceList훅을 통한 워크스페이스 데이터 페칭 진행
  • useInfiteScroll, useVirtualScroll 훅을 통해 기존 무한스크롤, 가상스크롤 적용
코드
export const WorkspaceContainer = () => {
  const { hasNextPage, fetchNextPage, isPending, isFetchingNextPage, workspaceList } =
    useGetWorkspaceList();

  const { renderedData, offsetY, totalHeight } = useVirtualScroll<TWorkspace>({
    data: workspaceList,
    topSectionHeight: 594,
    renderedItemHeight: 262,
    gapY: 32,
  });

  const fetchCallback: IntersectionObserverCallback = (entries, observer) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting && hasNextPage) {
        fetchNextPage();
        observer.unobserve(entry.target);
      }
    });
  };

  const nextFetchTargetRef = useInfiniteScroll({ intersectionCallback: fetchCallback });

  return (
    <>
      {workspaceList &&
        (workspaceList.length === 0 ? (
          <EmptyWorkspace />
        ) : (
          <div
            style={{
              height: `${totalHeight}px`,
            }}
          >
            <WorkspaceGrid offsetY={offsetY}>
              <WorkspaceList workspaceList={renderedData} />
              {isFetchingNextPage && <SkeletonWorkspaceList skeletonNum={8} />}
            </WorkspaceGrid>
          </div>
        ))}
      {!isPending && !isFetchingNextPage && hasNextPage && (
        <div ref={nextFetchTargetRef} className="h-3 w-full"></div>
      )}
    </>
  );
};

🔥 Trouble Shooting (해결된 문제 및 해결 과정)

  • 에러 처리를 위해 ErrorBoundary를 직접 구현하였으나, 이미 react-router에서 제공하는 errorElement를 통해 에러 처리를 하였기에 기존 코드를 전부 수정하는 작업은 비용이 너무 크다고 생각이 들었습니다. Workspace 조회 시 404 에러만 따로 처리해주는 WorkspaceErrorPage를 만들었습니다.
  • 에러 처리 미들웨어에서 에러 발생 시 500 에러만 반환하는 문제가 있었습니다. 그래서 사용자 정의 에러들도 반환하도록 간단하게 수정했습니다.
  • 400 에러와 404에러의 코드와 메세지가 뒤바뀌어 있어 수정하였습니다.

🤔 Open Problem (미해결된 문제 혹은 고민사항)

  • 문서화를 별로하지 못했습니다. 수목에 진행해서 공유하겠습니다.

@lee0jae330 lee0jae330 added the refactor 리팩토링 label Jan 14, 2025
@lee0jae330 lee0jae330 self-assigned this Jan 14, 2025
@lee0jae330 lee0jae330 requested a review from a team as a code owner January 14, 2025 16:07
@lee0jae330 lee0jae330 requested review from Ujaa and inhachoi and removed request for a team January 14, 2025 16:07
@Ujaa
Copy link
Contributor

Ujaa commented Jan 15, 2025

suspense 문서화 너무 잘해주셨는데요? 읽으면서 왜 suspense를 써야하는지 알 수 있었습니다. 고생하셨습니다 ❤️

Copy link
Contributor

@inhachoi inhachoi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React의 철학인 선언적인 프로그래밍을 적극적으로 반영하고자 기존 명령형 프로그래밍 성격이 강했던 기존 방식을 Suspense를 활용한 방식으로 바꾸고자 진행한 작업입니다.

위 멘트가 상당히 개발자스러워서 멋있었습니다 ㅎㅎ

영재님의 PR은 매번 큰 울림을 주네요. 숭배하겠습니다 ❤️

<WorkspaceContainer />
<WorkspaceSection />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

컴포넌트 의미가 좀 더 명확해져서 좋네요!

export const WorkspaceErrorPage = () => {
const error: any = useRouteError();
const statusCode = error?.response?.statusCode || error?.status;
console.log('error', error);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

console.log를 제거를 깜빡하신것 같아유 😊

Comment on lines -39 to -49
if (isError) {
toast.error('워크스페이스 정보 불러오기 실패');
return;
}
if (!data) {
if (!isError || !data || !data.workspaceDto) {
return;
}

if (!data.workspaceDto) {
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if문 최소화 좋네요 👍

import { errorStatus } from '../utils/constants';

// eslint-disable-next-line no-unused-vars
export const errorMiddleware = (err: Error, req: Request, res: Response, _next: NextFunction) => {
console.log(err.constructor.name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

console.log를 제거를 깜빡하신것 같아유 😊 222

@lee0jae330 lee0jae330 merged commit 0163d1f into dev Jan 15, 2025
5 checks passed
@lee0jae330 lee0jae330 deleted the refactor/18 branch January 15, 2025 05:38
Honghyeonji added a commit that referenced this pull request Jan 16, 2025
* 🔨 refactor: Docker 이미지 최적화를 위한 코드 리팩토링

* 🙀 chore: 오타 수정

* 🐛 fix: COPY 경로 수정

* 🐛 fix: swagger-auto 명령어 추가

* 🙀 chore: 오타수정

* 🐛 fix: backend 이미지가 base-image를 사용하지 않으므로 새로운 패키지 매니저 설치 및 추가 파일 복사하는 로직 추가

* 🐛 fix: pnpm-lock 복사 코드 추가

* 🐛 fix: 서버 패키지 설치 안되는 오류 해결하기 위해 코드 수정

* 🐛 fix: eslint 경로 체크용 package 폴더 추가 복사

* 🐛 fix: 의존성을 복사해오고 dev용을 지우는 방식으로 수정

* 🐛 fix: pnpm-workspace 파일 복사

* 🙀 chore: cicd 스크립트 오타 수정

* 🙀 chore: copy 명령어 합침

* 🙀 chore: 코드 구조 변경

* 🐛 fix: COPY 경로 수정

* 🙀 chore: 경로 오타 수정

* 🔨 refactor: 배포시 swagger-auto 안 하게 로직 수정 및 prod 종속성에 필요한 패키지 dev 종속성에서 이동

* 🙀 chore: 경로 오타 수정

* 🙀 chore: 안쓰는 라이브러리 삭제

* 🚨 !HOTFIX!: env 설정 누락된 코드 추가

* 🚨 !HOTFIX!: env 설정 누락된 코드 추가

* [#10] 홈페이지 가상스크롤 적용 (#14)

* ✨ feat: scroll의 Y 좌표를 리턴하는 useScroll 커스텀 훅 추가

* 🚚 rename: hooks/css에 있던 useWindowSize 훅 폴더 위치 변경

* ✨ feat: 가상스크롤 구현 중

* 🙀 chore: 함수명 오타 수정

* ✨ feat: 가상스크롤 커스텀훅 추가

* ✨ feat: WorkspaceGrid 컴포넌트에 가상스크롤 적용

* 🙀 chore: grid의 총 높이 계산할 때 반올림   적용

* [#11] Google Analytics 적용 (#15)

* ✨ feat: ga4 코드 추가

* 🔨 refactor: 로컬 환경 디버깅용 코드로 전환

* 🙀 chore: GA 디버깅 코드 삭제

* ✨ feat: 이벤트 트레이싱

* Update boolock-dev-cicd.yml

* Update boolock-dev-cicd.yml

* [#18] useQuery, useInfiniteQuery -> useSuspenseQuery, useSuspenseInfiniteQuery 교체 (#19)

* 🔨 refactor: useQuery를 useSuspenseQuery로 교체 및 error 처러 코드 삭제

* 🔨 refactor: 로딩 UI 및 에러 처리 코드 삭제

* 🔨 refactor: suspense 적용 및 error boundy fallback에 workspace 에러 페이지 설정

* 🔨 refactor: useInfinityQuery -> useSuspenseQuery로 교체

* 🙀 chore: 400 에러와 404에러의 에러 코드 및 상태 메세지가 잘못 설정 되어 있어 올바르게 수정

* 🐛 fix: 기존 에러 발생 시 500 에러로만 응답하는 문제 해결

* 🔨 refactor: workspaceContainer에서 워크스페이스 데이터를 렌더링하고 페칭하는 부분을 분리함

* 🙀 chore: 컴포넌트 분리에 따른 코드 수정

* 🙀 chore: github action 에서 파일명 변경을 감지하지 못한 문제로 인해 파일명 변경

* 🙀 chore: 불필요한 console.log 삭제

* [#21] 홈페이지 로딩 시 스켈레톤UI에 그리드가 적용되지 않는 문제 해결, 워크스페이스 로딩 화면 조건부 렌더링 (#22)

* 🐛 fix: 스켈레톤UI에 그리드가 안되는 문제 해결

* ✨ feat: 워크스페이스 로딩 시간이 0.05초 이상일 때만 로딩 화면이 렌더링되도록 변경

* 🚨 !HOTFIX!: error가 발생할 때 return 해야하는데 그렇지 않을 때 return 하여 workspace가 초기화되지않는 문제 해결

* 🚨 !HOTFIX!: workflow on 설정 main push 일 경우로 수정

---------

Co-authored-by: YEONGJAE LEE <[email protected]>
Co-authored-by: Gyeungil Choi <[email protected]>
Co-authored-by: Yujin <[email protected]>
Co-authored-by: lee0jae330 <[email protected]>
Honghyeonji added a commit that referenced this pull request Jan 17, 2025
* 🔨 refactor: Docker 이미지 최적화를 위한 코드 리팩토링

* 🙀 chore: 오타 수정

* 🐛 fix: COPY 경로 수정

* 🐛 fix: swagger-auto 명령어 추가

* 🙀 chore: 오타수정

* 🐛 fix: backend 이미지가 base-image를 사용하지 않으므로 새로운 패키지 매니저 설치 및 추가 파일 복사하는 로직 추가

* 🐛 fix: pnpm-lock 복사 코드 추가

* 🐛 fix: 서버 패키지 설치 안되는 오류 해결하기 위해 코드 수정

* 🐛 fix: eslint 경로 체크용 package 폴더 추가 복사

* 🐛 fix: 의존성을 복사해오고 dev용을 지우는 방식으로 수정

* 🐛 fix: pnpm-workspace 파일 복사

* 🙀 chore: cicd 스크립트 오타 수정

* 🙀 chore: copy 명령어 합침

* 🙀 chore: 코드 구조 변경

* 🐛 fix: COPY 경로 수정

* 🙀 chore: 경로 오타 수정

* 🔨 refactor: 배포시 swagger-auto 안 하게 로직 수정 및 prod 종속성에 필요한 패키지 dev 종속성에서 이동

* 🙀 chore: 경로 오타 수정

* 🙀 chore: 안쓰는 라이브러리 삭제

* 🚨 !HOTFIX!: env 설정 누락된 코드 추가

* 🚨 !HOTFIX!: env 설정 누락된 코드 추가

* [#10] 홈페이지 가상스크롤 적용 (#14)

* ✨ feat: scroll의 Y 좌표를 리턴하는 useScroll 커스텀 훅 추가

* 🚚 rename: hooks/css에 있던 useWindowSize 훅 폴더 위치 변경

* ✨ feat: 가상스크롤 구현 중

* 🙀 chore: 함수명 오타 수정

* ✨ feat: 가상스크롤 커스텀훅 추가

* ✨ feat: WorkspaceGrid 컴포넌트에 가상스크롤 적용

* 🙀 chore: grid의 총 높이 계산할 때 반올림   적용

* [#11] Google Analytics 적용 (#15)

* ✨ feat: ga4 코드 추가

* 🔨 refactor: 로컬 환경 디버깅용 코드로 전환

* 🙀 chore: GA 디버깅 코드 삭제

* ✨ feat: 이벤트 트레이싱

* Update boolock-dev-cicd.yml

* Update boolock-dev-cicd.yml

* [#18] useQuery, useInfiniteQuery -> useSuspenseQuery, useSuspenseInfiniteQuery 교체 (#19)

* 🔨 refactor: useQuery를 useSuspenseQuery로 교체 및 error 처러 코드 삭제

* 🔨 refactor: 로딩 UI 및 에러 처리 코드 삭제

* 🔨 refactor: suspense 적용 및 error boundy fallback에 workspace 에러 페이지 설정

* 🔨 refactor: useInfinityQuery -> useSuspenseQuery로 교체

* 🙀 chore: 400 에러와 404에러의 에러 코드 및 상태 메세지가 잘못 설정 되어 있어 올바르게 수정

* 🐛 fix: 기존 에러 발생 시 500 에러로만 응답하는 문제 해결

* 🔨 refactor: workspaceContainer에서 워크스페이스 데이터를 렌더링하고 페칭하는 부분을 분리함

* 🙀 chore: 컴포넌트 분리에 따른 코드 수정

* 🙀 chore: github action 에서 파일명 변경을 감지하지 못한 문제로 인해 파일명 변경

* 🙀 chore: 불필요한 console.log 삭제

* [#21] 홈페이지 로딩 시 스켈레톤UI에 그리드가 적용되지 않는 문제 해결, 워크스페이스 로딩 화면 조건부 렌더링 (#22)

* 🐛 fix: 스켈레톤UI에 그리드가 안되는 문제 해결

* ✨ feat: 워크스페이스 로딩 시간이 0.05초 이상일 때만 로딩 화면이 렌더링되도록 변경

* 🚨 !HOTFIX!: error가 발생할 때 return 해야하는데 그렇지 않을 때 return 하여 workspace가 초기화되지않는 문제 해결

* 🚨 !HOTFIX!: workflow on 설정 main push 일 경우로 수정

---------

Co-authored-by: YEONGJAE LEE <[email protected]>
Co-authored-by: Gyeungil Choi <[email protected]>
Co-authored-by: Yujin <[email protected]>
Co-authored-by: lee0jae330 <[email protected]>
Honghyeonji added a commit that referenced this pull request Jan 28, 2025
* 🔨 refactor: Docker 이미지 최적화를 위한 코드 리팩토링

* 🙀 chore: 오타 수정

* 🐛 fix: COPY 경로 수정

* 🐛 fix: swagger-auto 명령어 추가

* 🙀 chore: 오타수정

* 🐛 fix: backend 이미지가 base-image를 사용하지 않으므로 새로운 패키지 매니저 설치 및 추가 파일 복사하는 로직 추가

* 🐛 fix: pnpm-lock 복사 코드 추가

* 🐛 fix: 서버 패키지 설치 안되는 오류 해결하기 위해 코드 수정

* 🐛 fix: eslint 경로 체크용 package 폴더 추가 복사

* 🐛 fix: 의존성을 복사해오고 dev용을 지우는 방식으로 수정

* 🐛 fix: pnpm-workspace 파일 복사

* 🙀 chore: cicd 스크립트 오타 수정

* 🙀 chore: copy 명령어 합침

* 🙀 chore: 코드 구조 변경

* 🐛 fix: COPY 경로 수정

* 🙀 chore: 경로 오타 수정

* 🔨 refactor: 배포시 swagger-auto 안 하게 로직 수정 및 prod 종속성에 필요한 패키지 dev 종속성에서 이동

* 🙀 chore: 경로 오타 수정

* 🙀 chore: 안쓰는 라이브러리 삭제

* 🚨 !HOTFIX!: env 설정 누락된 코드 추가

* 🚨 !HOTFIX!: env 설정 누락된 코드 추가

* [#10] 홈페이지 가상스크롤 적용 (#14)

* ✨ feat: scroll의 Y 좌표를 리턴하는 useScroll 커스텀 훅 추가

* 🚚 rename: hooks/css에 있던 useWindowSize 훅 폴더 위치 변경

* ✨ feat: 가상스크롤 구현 중

* 🙀 chore: 함수명 오타 수정

* ✨ feat: 가상스크롤 커스텀훅 추가

* ✨ feat: WorkspaceGrid 컴포넌트에 가상스크롤 적용

* 🙀 chore: grid의 총 높이 계산할 때 반올림   적용

* [#11] Google Analytics 적용 (#15)

* ✨ feat: ga4 코드 추가

* 🔨 refactor: 로컬 환경 디버깅용 코드로 전환

* 🙀 chore: GA 디버깅 코드 삭제

* 🔨 refactor: workflow 에 dockerhub 사용하는 코드 제거

* ✨ feat: 이벤트 트레이싱

* 🔨 refactor: docker hub 로그인 부분 삭제

* 🔨 refactor: workflow와 compose 파일 dockerhub 쓰는 스크립트로 수정

* 🐛 fix: dockerhub 쓰는 버전에서는 build단계에서 pnpm 설치가 필요 없으니 해당 코드 삭제

* 🔨 refactor: deploy단계에서 docker hub 로그인 하는 부분 이동

* 🙀 chore: git 상태 확인하는 코드 추가

* 🙀 chore: docker compose cache_from 부분 삭제(dockerhub에서 가져올 땐 필요 없음)

* 🙀 chore: docker hub 로그인 방식 수정

* 🙀 chore: 안쓰는 옵션 삭제

* 🐛 fix: base-image 이름 변경

* 🙀 chore: 언더바 하이픈으로 수정

* 🙀 chore: 안쓰는 코드 삭제

* 🐛 fix: dockercompose 코드에서 build내에 image 잘 못 넣은 코드 수정

* 🙀 chore: docker 로그인 확인을 위한 docker info 코드 추가

* 🔨 refactor: docker compose에서 base 이미지 가져오는 것을 명시적으로 표시

* 🙀 chore: docker compose config 확인을 위한 코드 추가

* 🙀 chore: docker compose 체크를 위한 경로 수정

* 🙀 chore: 필요없는 코드 삭제

* 🐛 fix: compose 파일에서 base 부분 삭제

* 🔨 refactor: docker 캐시 이용하는 방법으로 변경

* 🔨 refactor: docker tag 설정해주는 코드 추가

* 🙀 chore: 코드 변경

* 🔨 refactor: github actions 캐시사용하는 방식으로 변경

* 🔨 refactor: docker build 코드 cache 가져오게 수정

* 🔨 refactor: buildx 코드 추가

* 🔨 refactor: docker buildx 사용하는 방식 수정

* 🔨 refactor: base 이미지에 로컬태그를 붙여주는 방식 대신 레지스트리 경로를 명시적으로 표시하는 방식으로 수정

* 🔨 refactor: docker 이미지 빌드 때 사용하는 cache from-to 원격주소로 변경

* 🔨 refactor: github action 캐싱키 변경 및 docker 이미지 빌드 시 cache 주소 잘못 쓴 것 수정

* 🙀 chore: docker image output 명시적으로 작성

* 🔨 refactor: base image를 hub에 push하지 않고 로컬에서 빌드해서 그대로 사용하는 방식으로 수정

* 🙀 chore: latest 태그 제거

* 🙀 chore: 베이스 이미지 빌드할 때 load: true 옵션 추가

* 🔨 refactor: base-image도 docker hub에 올리는 방법으로 재수정

* 🙀 chore: username 잘 나오는지 확인

* 🙀 chore: set up docker buildx 에서 with 설정 추가

* 🙀 chore: 캐시 초기화 코드 추가

* 🙀 chore: build-args 넣어주는 방식 수정

* 🙀 chore: build-args 넣어주는 방식 수정

* Update boolock-dev-cicd.yml

* Update boolock-dev-cicd.yml

* 🙀 chore: 디버깅용 코드 추가

* 🔨 refactor: base image 로컬 빌드 및 사용으로 방법 변경

* 🔨 refactor: cache-from 타입 inline으로 변경

* 🙀 chore: github actions 로컬에 base-image가 잘 남겨져 있는지 확인하는 코드 추가

* [#18] useQuery, useInfiniteQuery -> useSuspenseQuery, useSuspenseInfiniteQuery 교체 (#19)

* 🔨 refactor: useQuery를 useSuspenseQuery로 교체 및 error 처러 코드 삭제

* 🔨 refactor: 로딩 UI 및 에러 처리 코드 삭제

* 🔨 refactor: suspense 적용 및 error boundy fallback에 workspace 에러 페이지 설정

* 🔨 refactor: useInfinityQuery -> useSuspenseQuery로 교체

* 🙀 chore: 400 에러와 404에러의 에러 코드 및 상태 메세지가 잘못 설정 되어 있어 올바르게 수정

* 🐛 fix: 기존 에러 발생 시 500 에러로만 응답하는 문제 해결

* 🔨 refactor: workspaceContainer에서 워크스페이스 데이터를 렌더링하고 페칭하는 부분을 분리함

* 🙀 chore: 컴포넌트 분리에 따른 코드 수정

* 🙀 chore: github action 에서 파일명 변경을 감지하지 못한 문제로 인해 파일명 변경

* 🙀 chore: 불필요한 console.log 삭제

* 🔨 refactor: base-image cache 루트 변경

* 🔨 refactor: type=local로 재변경

* 🔨 refactor: base-image load단계 추가

* 🙀 chore: 이미지 태그 삭제

* 🙀 chore: 이전 코드에서 캐싱 잘 되는지 확인용

* 🙀 chore: dockerhub_username arg 추가

* 🔨 refactor: 이전버전에 cache 경로만 수정

* 🙀 chore: build-args 추가

* 🔨 refactor: buildx 플러그인 초기화 옵션 + cache에서 이미지 사용시 모든 캐시 데이터를 최대한 활용하는 mode=max 옵션 추가

* 🙀 chore: base-image 캐싱 추가

* 🔨 refactor: base image 로컬 저장 및 hub push 둘 다 되게 수정

* 🙀 chore: verify 스텝 추가

* [#21] 홈페이지 로딩 시 스켈레톤UI에 그리드가 적용되지 않는 문제 해결, 워크스페이스 로딩 화면 조건부 렌더링 (#22)

* 🐛 fix: 스켈레톤UI에 그리드가 안되는 문제 해결

* ✨ feat: 워크스페이스 로딩 시간이 0.05초 이상일 때만 로딩 화면이 렌더링되도록 변경

* 🙀 chore: 오타 수정

* 🙀 chore: 아ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ

* 🔨 refactor: 원격에서 base-image 가져와서 load하는 방식으로 수정

* 🙀 chore: 경로 명시적으로 쓰기

* 🙀 chore: docker 네트워크 연결 테스트 코드 추가

* 🙀 chore: docker login 스텝 이동

* 🙀 chore: 토큰 코드 추가

* 🙀 chore: token 발급받는 부분 추가

* 🚨 !HOTFIX!: error가 발생할 때 return 해야하는데 그렇지 않을 때 return 하여 workspace가 초기화되지않는 문제 해결

* 🙀 chore: dockerfile FROM base image 경로를 직접적으로 입력하는 버전

* 🙀 chore: base-image outputs 타입을 oci로 변경

* 🙀 chore: docker 이미지 빌드 platform을 linux/amd64로 명시

* 🙀 chore: 타입 명시

* 🚨 !HOTFIX!: workflow on 설정 main push 일 경우로 수정

* ✨ feat: 서버 분할로 인해 cicd dev버전과 main 버전 분리 및 배포를 위한 설정 이분할

* 🙀 chore: 워크플로우 이름 변경

* 🙀 chore: 병합하면서 사라진 dev cicd의 on 조건 추가

* 🙀 chore: docker hub password token으로 변경

* 🙀 chore: client dockerfile 오타 수정

* 🙀 chore: dockerfile.test 오타 수정

* 🔨 refactor: cache type gha로 변경

* 🙀 chore: compose 배포 명령어 수정

* 🙀 chore: 두번 쓴 명령어 삭제

* 🙀 chore: env 설정 확인용 스크립트 추가

* 🙀 chore: cache docker layers 단계 없어도 동작하는지 확인

* 🙀 chore: 주석 제거

* 🔨 refactor: cache-from/to registry type으로 변경

* 🙀 chore: docker chche 타입 gha 타입으로 변경

* 🔨 refactor: github action deploy 과정 push에서만 사용되게 코드 추가

* 🔨 refactor: 브랜치별 워크플로우 시나리오 분리

* 🙀 chore: docker arg 선언 줄분리

* 🔨 refactor: docker compose 파일 type env 설정에 따른 port 설정해주는 코드 추가

* 🔨 refactor: HTTP/1.1 -> HTTP/2.0 개선 설정 추가

* 🔨 refactor: HTTP/2.0 -> HTTP/3.0 개선 설정 추가

* [HOTFIX] cicd 및 docker-compose 코드 수정 (#29)

* 🙀 chore: compose 코드 수정

* 🙀 chore: 현재 브랜치에서 deploy 체크하게 브랜치 설정코드 수정

* 🙀 chore: ssl_port 빈칸 표시

* 🙀 chore: # 처리 삭제

* 🙀 chore: 아예 SSL_PORT 설정 없애보기

* 🙀 chore: 우회방식 사용

* 🔨 refactor: docker compose 파일 test 버전 추가 및 cicd 코드 수정

* 🙀 chore: 합치기 전 설정 수정

* [#31] “Code 하이라이팅” 코드 품질 개선 (#36)

* 🔨 refactor: 변수 유틸함수로 분리

* 🔨 refactor: 애니메이션 코드 커스텀 훅으로 분리

* 🙀 chore: 훅에 주석 처리

* 🔨 refactor: 애니메이션 지속 시간 (매직넘버) 상수화

* 🙀 chore: 오타 수정

* 🔨 refactor: 클래스명 계산 로직 추상화

* 🔨 refactor: 마우스 호버 이벤트 훅 관리 + 라인클래스이름 추상화

* 🔨 refactor: 파싱 코드 추상화 + 함수 설명 주석 추가

* 🔨 refactor: Props Drilling이 나타나는 컴포넌트를 삭제하고 부모 컴포넌트로 이전.

* 🔨 refactor: viewer 클래스명 생성 함수 분리

* 🔨 refactor: 타입 분리 + index.ts로 import 문 간소화하여 가독성 개선

* [#26] 워크스페이스 페이지의 불필요한 리렌더링 개선 (#35)

* ✨ feat: css 속성 물음표 아이콘 좌표를 전역 상태로 관리하는 것이 아닌 local 상태 변수를 통해 관리하도록 변경

* Revert "✨ feat: css 속성 물음표 아이콘 좌표를 전역 상태로 관리하는 것이 아닌 local 상태 변수를 통해 관리하도록 변경"

This reverts commit b4409ef.

* 🔨 refactor: css속성 물음표 아이콘 좌표를 전역상태가 아닌 local 상태로 관리

* 🔨 refactor: 기존에 사용하던 매직넘버를 삭제하고 useLayoutEffect를 통해 툴팁의 높이를 직접 측정하고 툴팁의 좌표를 계산하는 방식으로 변경

* 🔨 refactor: css item 물음표 아이콘 위치를 전역 상태가 아닌 로컬 상태변수로 관리하도록 변경, 불필요한 cssTooltiptore 삭제

* 🔨 refactor: useCssTooltip 훅을 통해 좌표 계산을 하도록 변경

* 🙀 chore: 타입 단언 대신 타입 선언으로 변경경

* 🙀 chore: 불필요한 변수 및 반환값 삭제

* 🙀 chore: 커스텀 select에서 사용하는 type 및 enum type 폴더로 분리

* 🔨 refactor: css 클래스 리스트를 만드는 로직을 커스텀 훅으로 분리

* 🔨 refactor: useCssPropsStore에서 각 상태를 구조분해할당으로 사용하여 모든 상태를 구독하여 불필요한 리렌더링이 발생하는 문제를 해결함

* 🎨 style: 불필요한 스타일 코드 삭제

* 🙀 chore: 변경된 props 반영

* [#25] 사용자가이드 단계 이동시 헤더 내 모든 요소 리렌더링 개선 (#37)

* 🎨 style: 도움말버튼 컴포넌트 분리 (HelpButton)

* 🔨 refactor: 코치마크 단계 이동시 도움말버튼 리렌더링 개선

* 🔨 refactor: 헤더 상단 버튼 각각 메모이제이션

* 🔨 refactor: 코치마크 4단계로 이동하거나 4단계 였던 경우에만 HeaderButtons 리렌더링 되도록  메모이제이션

* 🔨 refactor: 워크스페이스 헤더 리렌더링 개선 완료

* 🐛 fix: 대소문자 오타 수정

* 📝 docs: README 수정

* [#34] 수동 저장 -> 자동 저장으로 변경 (#38)

* 🙀 chore: build시 오류 생기는 코드 제거

---------

Co-authored-by: YEONGJAE LEE <[email protected]>
Co-authored-by: Gyeungil Choi <[email protected]>
Co-authored-by: Yujin <[email protected]>
Co-authored-by: lee0jae330 <[email protected]>
Co-authored-by: chichoc <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactor 리팩토링
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[refactor] useQuery, useInfinityQuery를 Suspense 기반 useSuspenseQuery, useSuspenseInfinityQuery로 변경
3 participants